#ifndef __YUECHUAN_ENDIAN_HPP
#define __YUECHUAN_ENDIAN_HPP



#define YUECHUAN_LITTLE_ENDIAN 1
#define YUECHUAN_BIG_ENDIAN 2

#include <byteswap.h>
#include <stdint.h>
#include <type_traits>

namespace yuechuan {
    template<class T>
    typename std::enable_if<sizeof(T) == sizeof(uint64_t), T>::type byteSwap(T value) {
        return (T) bswap_64((uint64_t) value);
    }

    template<class T>
    typename std::enable_if<sizeof(T) == sizeof(uint32_t), T>::type byteSwap(T value) {
        return (T) bswap_32((uint32_t) value);
    }

    template<class T>
    typename std::enable_if<sizeof(T) == sizeof(uint16_t), T>::type byteSwap(T value) {
        return (T) bswap_16((uint16_t) value);
    }

#if BYTE_ORDER == BIG_ENDIAN
#define YUECHUAN_BYTE_ORDER YUECHUAN_BIG_ENDIAN
#else
#define YUECHUAN_BYTE_ORDER YUECHUAN_LITTLE_ENDIAN
#endif

#if YUECHUAN_BYTE_ORDER == YUECHUAN_BIG_ENDIAN

    /**
     * @brief 只爱小端机器上执行byteswap，在大端机器上什么都不做
     */
    template<class T>
    T byteswapOnLittleEndian(T t) {
        return t;
    }

    /**
     * @brief 只在大端机器上执行byteswap,在小端机器上什么都不做
     */
    template<class T>
    T byteswapOnBigEndian(T t) {
        return byteSwap(t);
    }

#else

    /**
     * @brief 只在小端机器上执行byteSwap，在大端机器上什么都不做
     */
    template<class T>
    T byteswapOnLittleEndian(T t){
        return byteSwap(t);
    }

    /**
     * @brief 只在大端机器上执行byteSwap，在小端机器上什么都不做
     */
    template<class T>
    T byteswapOnBigEndian(T t){
        return t;
    }
#endif
}//namespace yuechuan

#endif //__YUECHUAN_ENDIAN_HPP